In [15]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA  # Usaremos ARIMA con d=0 para simular ARMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame GOOG:", list(goog_df.columns))

# Verificar columna " Close"
columna_esperada = " Close"
if columna_esperada in pep_df.columns and columna_esperada in goog_df.columns:
    columna_cierre = columna_esperada
    print(f"Se encontró '{columna_esperada}' en ambos DataFrames, usándola para precios de cierre")
else:
    while True:
        columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ").strip()
        if columna_cierre in pep_df.columns and columna_cierre in goog_df.columns:
            break
        else:
            print(f"Error: '{columna_cierre}' no encontrada en uno o ambos DataFrames")

# Extraer y limpiar precios de cierre
pep_close = pep_df[columna_cierre].dropna()
goog_close = goog_df[columna_cierre].dropna()

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(goog_close))
pep_close = pep_close[:min_longitud]
goog_close = goog_close[:min_longitud]

# Verificación de datos
print("Resumen de datos PEP Close:", pep_close.describe())
print("Resumen de datos GOOG Close:", goog_close.describe())
if len(pep_close) < 10:
    raise ValueError("Datos insuficientes para PEP")

# Pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")

    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(goog_close, "3MIN 3D GOOG")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: PEP y GOOG están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre PEP y GOOG")

coint_df = pd.DataFrame({'PEP': pep_close, 'GOOG': goog_close})
cointegration_test(coint_df)

# Función ARMA (usando ARIMA con d=0)
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except Exception as e:
                print(f"No se pudo ajustar ARMA({p},{q}) para {name}: {str(e)}")
                continue

    if mejor_orden is None:
        print(f"Advertencia: No se encontró un modelo ARMA válido para {name}. Usando predeterminado (1,0,1)")
        mejor_orden = (1, 0, 1)
        mejor_aic = float('inf')
    else:
        print(f"\nMejor modelo ARMA para {name}:")
        print(f"Orden: {mejor_orden}")
        print(f"AIC: {mejor_aic:.2f}")
        print("Interpretación:")
        print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
        print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar modelos ARMA
pep_orden = find_best_arma(pep_close, "3MIN 3D PEP")
goog_orden = find_best_arma(goog_close, "3MIN 3D GOOG")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
goog_modelo = ARIMA(goog_close, order=goog_orden).fit()

# Pronóstico
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)

# Graficar
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 3MIN 3D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 3MIN 3D PEP', color='red')
plt.plot(goog_close, label='Histórico 3MIN 3D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 3MIN 3D GOOG', color='green')
plt.title('Precios de cierre de 3MIN 3D PEP y 3MIN 3D GOOG con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")

plot_forecast(pep_modelo, pep_close, "3MIN 3D PEP")
plot_forecast(goog_modelo, goog_close, "3MIN 3D GOOG")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (5).xlsx
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG.xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Se encontró ' Close' en ambos DataFrames, usándola para precios de cierre
Resumen de datos PEP Close: count    455.000000
mean     155.048004
std        1.622073
min      152.610000
25%      154.070000
50%      154.580000
75%      155.972500
max      159.895000
Name:  Close, dtype: float64
Resumen de datos GOOG Close: count    455.000000
mean     173.389516
std        1.801465
min      167.890000
25%      172.483000
50%      173.810000
75%      174.550000
max      176.580000
Name:  Close, dtype: float64

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D PEP es no estacionario

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -1.0242
p-valor: 0.7443
Valores críticos: {'1%': -3.444836032925901, '5%': -2.8679272692747415, '10%': -2.5701721745036776}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.6108
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D GOOG es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [15.19566316  0.42522781]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
  - r = 1: No hay cointegración al 95% de confianza
Conclusión: No hay evidencia de cointegración entre PEP y GOOG
<ipython-input-15-3415b7bae42b>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-15-3415b7bae42b>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -99.05
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 3)
AIC: 211.48
Interpretación:
  - p=3: 3 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D PEP:
Último valor observado: 157.35
Valor promedio del pronóstico: 157.26
Cambio en el pronóstico: -0.09
Tendencia: Pronóstico a la baja
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D GOOG:
Último valor observado: 168.88
Valor promedio del pronóstico: 169.62
Cambio en el pronóstico: 0.74
Tendencia: Pronóstico al alza

Valores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):
455    157.329568
456    157.328138
457    157.302106
458    157.317722
459    157.295289
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):
455    169.022986
456    169.136038
457    169.023922
458    169.136907
459    169.272816
Name: predicted_mean, dtype: float64
In [16]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame GOOG:", list(goog_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    goog_close = goog_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(goog_close))
pep_close = pep_close[:min_longitud]
goog_close = goog_close[:min_longitud]

# Función para pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(goog_close, "3MIN 3D GOOG")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"r = {i}: No hay cointegración al 95% de confianza")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'GOOG': goog_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "3MIN 3D PEP")
goog_orden = find_best_arma(goog_close, "3MIN 3D GOOG")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
goog_modelo = ARIMA(goog_close, order=goog_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 3MIN 3D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 3MIN 3D PEP', color='red')
plt.plot(goog_close, label='Histórico 3MIN 3D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 3MIN 3D GOOG', color='green')
plt.title('Precios de cierre de 3MIN 3D PEP y 3MIN 3D GOOG con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

# Generar gráficos de pronóstico detallados
plot_forecast(pep_modelo, pep_close, "3MIN 3D PEP")
plot_forecast(goog_modelo, goog_close, "3MIN 3D GOOG")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (6).xlsx
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (1).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -1.0242
p-valor: 0.7443
Valores críticos: {'1%': -3.444836032925901, '5%': -2.8679272692747415, '10%': -2.5701721745036776}

Prueba KPSS:
Estadístico KPSS: 1.6108
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Prueba de cointegración de Johansen:
Estadístico de traza: [15.19566316  0.42522781]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
r = 0: No hay cointegración al 95% de confianza
r = 1: No hay cointegración al 95% de confianza
<ipython-input-16-6c19117dd346>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-16-6c19117dd346>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -99.05
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 3)
AIC: 211.48
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Valores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):
455    157.329568
456    157.328138
457    157.302106
458    157.317722
459    157.295289
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):
455    169.022986
456    169.136038
457    169.023922
458    169.136907
459    169.272816
Name: predicted_mean, dtype: float64
In [17]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame GOOG:", list(goog_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    goog_close = goog_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(goog_close))
pep_close = pep_close[:min_longitud]
goog_close = goog_close[:min_longitud]

# Función para pruebas de raíz unitaria con interpretación
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(goog_close, "3MIN 3D GOOG")

# Prueba de cointegración con interpretación
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) > valor crítico 95% ({result.cvt[i, 1]:.2f})")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) <= valor crítico 95% ({result.cvt[i, 1]:.2f})")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: PEP y GOOG están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre PEP y GOOG")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'GOOG': goog_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA con interpretación
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    print("Interpretación:")
    print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
    print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "3MIN 3D PEP")
goog_orden = find_best_arma(goog_close, "3MIN 3D GOOG")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
goog_modelo = ARIMA(goog_close, order=goog_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 3MIN 3D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 3MIN 3D PEP', color='red')
plt.plot(goog_close, label='Histórico 3MIN 3D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 3MIN 3D GOOG', color='green')
plt.title('Precios de cierre de 3MIN 3D PEP y 3MIN 3D GOOG con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza e interpretación
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")
    print(f"Rango del intervalo de confianza 95% en el período {steps}: [{intervalo_conf.iloc[-1, 0]:.2f}, {intervalo_conf.iloc[-1, 1]:.2f}]")

# Generar gráficos de pronóstico detallados e interpretaciones
plot_forecast(pep_modelo, pep_close, "3MIN 3D PEP")
plot_forecast(goog_modelo, goog_close, "3MIN 3D GOOG")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (7).xlsx
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (2).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D PEP es no estacionario

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -1.0242
p-valor: 0.7443
Valores críticos: {'1%': -3.444836032925901, '5%': -2.8679272692747415, '10%': -2.5701721745036776}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.6108
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D GOOG es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [15.19566316  0.42522781]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
    Estadístico de traza (15.20) <= valor crítico 95% (15.49)
  - r = 1: No hay cointegración al 95% de confianza
    Estadístico de traza (0.43) <= valor crítico 95% (3.84)
Conclusión: No hay evidencia de cointegración entre PEP y GOOG
<ipython-input-17-e515072dba2d>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-17-e515072dba2d>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -99.05
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 3)
AIC: 211.48
Interpretación:
  - p=3: 3 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D PEP:
Último valor observado: 157.35
Valor promedio del pronóstico: 157.26
Cambio en el pronóstico: -0.09
Tendencia: Pronóstico a la baja
Rango del intervalo de confianza 95% en el período 30: [155.52, 158.89]
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D GOOG:
Último valor observado: 168.88
Valor promedio del pronóstico: 169.62
Cambio en el pronóstico: 0.74
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [167.40, 172.99]

Valores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):
455    157.329568
456    157.328138
457    157.302106
458    157.317722
459    157.295289
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):
455    169.022986
456    169.136038
457    169.023922
458    169.136907
459    169.272816
Name: predicted_mean, dtype: float64
In [18]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame GOOG:", list(goog_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    goog_close = goog_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud y eliminar valores nulos
min_longitud = min(len(pep_close), len(goog_close))
pep_close = pep_close[:min_longitud].dropna()
goog_close = goog_close[:min_longitud].dropna()

# Paso 1: Determinar tendencia y estacionalidad
def plot_trend_seasonality(series, name):
    plt.figure(figsize=(12, 6))
    plt.plot(series, label=f'Precios {name}')
    plt.title(f'Precios de cierre de {name}')
    plt.legend()
    plt.show()

    # Descomposición (período 30 para datos de 3 minutos, ajustar si es necesario)
    decomposition = seasonal_decompose(series, model='additive', period=30)
    tendencia = decomposition.trend
    estacionalidad = decomposition.seasonal
    residuo = decomposition.resid

    plt.figure(figsize=(12, 8))
    plt.subplot(411)
    plt.plot(series, label='Original')
    plt.legend(loc='upper left')
    plt.subplot(412)
    plt.plot(tendencia, label='Tendencia')
    plt.legend(loc='upper left')
    plt.subplot(413)
    plt.plot(estacionalidad, label='Estacionalidad')
    plt.legend(loc='upper left')
    plt.subplot(414)
    plt.plot(residuo, label='Residuos')
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()

    print(f"\nAnálisis para {name}:")
    print("- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.")
    print("- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.")

plot_trend_seasonality(pep_close, "3MIN 3D PEP")
plot_trend_seasonality(goog_close, "3MIN 3D GOOG")

# Paso 2: Determinar si los datos son estacionarios
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(goog_close, "3MIN 3D GOOG")

# Paso 3: Dividir datos en entrenamiento (90%) y prueba (10%)
tamano_entrenamiento = int(len(pep_close) * 0.9)
pep_entrenamiento, pep_prueba = pep_close[:tamano_entrenamiento], pep_close[tamano_entrenamiento:]
goog_entrenamiento, goog_prueba = goog_close[:tamano_entrenamiento], goog_close[tamano_entrenamiento:]

print(f"\nDivisión de datos:")
print(f"PEP - Tamaño entrenamiento: {len(pep_entrenamiento)}, Tamaño prueba: {len(pep_prueba)}")
print(f"GOOG - Tamaño entrenamiento: {len(goog_entrenamiento)}, Tamaño prueba: {len(goog_prueba)}")

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA en datos de entrenamiento
pep_orden = find_best_arma(pep_entrenamiento, "3MIN 3D PEP")
goog_orden = find_best_arma(goog_entrenamiento, "3MIN 3D GOOG")

pep_modelo = ARIMA(pep_entrenamiento, order=pep_orden).fit()
goog_modelo = ARIMA(goog_entrenamiento, order=goog_orden).fit()

# Pronosticar para el período de prueba
pasos_prueba = len(pep_prueba)
pep_pronostico = pep_modelo.forecast(steps=pasos_prueba)
goog_pronostico = goog_modelo.forecast(steps=pasos_prueba)

# Graficar entrenamiento, prueba y pronóstico
def plot_train_test_forecast(entrenamiento, prueba, pronostico, name):
    indice_pronostico = range(len(entrenamiento), len(entrenamiento) + len(prueba))
    plt.figure(figsize=(12, 6))
    plt.plot(entrenamiento, label=f'{name} Entrenamiento')
    plt.plot(range(len(entrenamiento), len(entrenamiento) + len(prueba)), prueba, label=f'{name} Prueba')
    plt.plot(indice_pronostico, pronostico, label=f'{name} Pronóstico', color='red')
    plt.title(f'{name} Entrenamiento, Prueba y Pronóstico')
    plt.legend()
    plt.show()

plot_train_test_forecast(pep_entrenamiento, pep_prueba, pep_pronostico, "3MIN 3D PEP")
plot_train_test_forecast(goog_entrenamiento, goog_prueba, goog_pronostico, "3MIN 3D GOOG")

# Evaluar precisión del pronóstico
pep_mse = mean_squared_error(pep_prueba, pep_pronostico)
goog_mse = mean_squared_error(goog_prueba, goog_pronostico)
print(f"\nPrecisión del pronóstico:")
print(f"PEP Error cuadrático medio: {pep_mse:.2f}")
print(f"GOOG Error cuadrático medio: {goog_mse:.2f}")
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (8).xlsx
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (3).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close
No description has been provided for this image
No description has been provided for this image
Análisis para 3MIN 3D PEP:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.
No description has been provided for this image
No description has been provided for this image
Análisis para 3MIN 3D GOOG:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D PEP es no estacionario

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -1.0242
p-valor: 0.7443
Valores críticos: {'1%': -3.444836032925901, '5%': -2.8679272692747415, '10%': -2.5701721745036776}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.6108
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D GOOG es no estacionario

División de datos:
PEP - Tamaño entrenamiento: 409, Tamaño prueba: 46
GOOG - Tamaño entrenamiento: 409, Tamaño prueba: 46
<ipython-input-18-c69905113927>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-18-c69905113927>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -194.05
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 2)
AIC: 175.96
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Precisión del pronóstico:
PEP Error cuadrático medio: 2.74
GOOG Error cuadrático medio: 15.58
In [19]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Verificar columna " Close"
columna_esperada = " Close"
if columna_esperada in goog_df.columns and columna_esperada in ko_df.columns:
    columna_cierre = columna_esperada
    print(f"Se encontró '{columna_esperada}' en ambos DataFrames, usándola para precios de cierre")
else:
    while True:
        columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ").strip()
        if columna_cierre in goog_df.columns and columna_cierre in ko_df.columns:
            break
        else:
            print(f"Error: '{columna_cierre}' no encontrada en uno o ambos DataFrames")

# Extraer y limpiar precios de cierre
goog_close = goog_df[columna_cierre].dropna()
ko_close = ko_df[columna_cierre].dropna()

# Asegurar misma longitud
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Verificación de datos
print("Resumen de datos GOOG Close:", goog_close.describe())
print("Resumen de datos KO Close:", ko_close.describe())
if len(goog_close) < 10:
    raise ValueError("Datos insuficientes para GOOG")

# Pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")

    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(goog_close, "3MIN 3D GOOG")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: GOOG y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre GOOG y KO")

coint_df = pd.DataFrame({'GOOG': goog_close, 'KO': ko_close})
cointegration_test(coint_df)

# Función ARIMA actualizada
def find_best_arima(series, name, max_p=3, max_d=2, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for d in range(max_d + 1):
            for q in range(max_q + 1):
                try:
                    modelo = ARIMA(series, order=(p, d, q))
                    resultados = modelo.fit()
                    if resultados.aic < mejor_aic:
                        mejor_aic = resultados.aic
                        mejor_orden = (p, d, q)
                except Exception as e:
                    print(f"No se pudo ajustar ARIMA({p},{d},{q}) para {name}: {str(e)}")
                    continue

    if mejor_orden is None:
        print(f"Advertencia: No se encontró un modelo ARIMA válido para {name}. Usando predeterminado (1,1,1)")
        mejor_orden = (1, 1, 1)
        mejor_aic = float('inf')
    else:
        print(f"\nMejor modelo ARIMA para {name}:")
        print(f"Orden: {mejor_orden}")
        print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar modelos ARIMA
goog_orden = find_best_arima(goog_close, "3MIN 3D GOOG")
ko_orden = find_best_arima(ko_close, "3MIN 3D KO")

goog_modelo = ARIMA(goog_close, order=goog_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronóstico
pasos_pronostico = 30
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Graficar
ultimo_indice = len(goog_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

plt.figure(figsize=(12,6))
plt.plot(goog_close, label='Histórico 3MIN 3D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 3MIN 3D GOOG', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D GOOG y 3MIN 3D KO con pronósticos')
plt.legend()
plt.show()

# Graficar pronóstico detallado
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")

plot_forecast(goog_modelo, goog_close, "3MIN 3D GOOG")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (4).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (5).xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Se encontró ' Close' en ambos DataFrames, usándola para precios de cierre
Resumen de datos GOOG Close: count    459.000000
mean     173.351168
std        1.840287
min      167.890000
25%      172.395000
50%      173.800000
75%      174.532500
max      176.580000
Name:  Close, dtype: float64
Resumen de datos KO Close: count    459.000000
mean      70.521504
std        0.674861
min       69.511600
25%       70.067500
50%       70.440000
75%       70.747500
max       72.500000
Name:  Close, dtype: float64

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -0.8569
p-valor: 0.8018
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.6762
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D GOOG es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.3740
p-valor: 0.9143
Valores críticos: {'1%': -3.4447721346720885, '5%': -2.8678991615065095, '10%': -2.570157193174823}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.9208
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [13.92472228  0.16259597]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
  - r = 1: No hay cointegración al 95% de confianza
Conclusión: No hay evidencia de cointegración entre GOOG y KO
<ipython-input-19-7f6ef67c73e1>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-19-7f6ef67c73e1>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARIMA para 3MIN 3D GOOG:
Orden: (2, 1, 2)
AIC: 222.94
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARIMA para 3MIN 3D KO:
Orden: (3, 1, 3)
AIC: -979.06
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D GOOG:
Último valor observado: 168.73
Valor promedio del pronóstico: 168.74
Cambio en el pronóstico: 0.02
Tendencia: Pronóstico al alza
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D KO:
Último valor observado: 72.15
Valor promedio del pronóstico: 72.15
Cambio en el pronóstico: 0.00
Tendencia: Pronóstico al alza

Valores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):
459    168.898495
460    168.628520
461    168.687425
462    168.893022
463    168.669270
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
459    72.166935
460    72.186740
461    72.179358
462    72.181974
463    72.166525
Name: predicted_mean, dtype: float64
In [20]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Verificar columna " Close"
columna_esperada = " Close"
if columna_esperada in goog_df.columns and columna_esperada in ko_df.columns:
    columna_cierre = columna_esperada
    print(f"Se encontró '{columna_esperada}' en ambos DataFrames, usándola para precios de cierre")
else:
    while True:
        columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ").strip()
        if columna_cierre in goog_df.columns and columna_cierre in ko_df.columns:
            break
        else:
            print(f"Error: '{columna_cierre}' no encontrada en uno o ambos DataFrames")

# Extraer y limpiar precios de cierre
goog_close = goog_df[columna_cierre].dropna()
ko_close = ko_df[columna_cierre].dropna()

# Asegurar misma longitud
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Verificación de datos
print("Resumen de datos GOOG Close:", goog_close.describe())
print("Resumen de datos KO Close:", ko_close.describe())
if len(goog_close) < 10:
    raise ValueError("Datos insuficientes para GOOG")

# Pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")

    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(goog_close, "3MIN 3D GOOG")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: GOOG y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre GOOG y KO")

coint_df = pd.DataFrame({'GOOG': goog_close, 'KO': ko_close})
cointegration_test(coint_df)

# Función ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except Exception as e:
                print(f"No se pudo ajustar ARMA({p},{q}) para {name}: {str(e)}")
                continue

    if mejor_orden is None:
        print(f"Advertencia: No se encontró un modelo ARMA válido para {name}. Usando predeterminado (1,0,1)")
        mejor_orden = (1, 0, 1)
        mejor_aic = float('inf')
    else:
        print(f"\nMejor modelo ARMA para {name}:")
        print(f"Orden: {mejor_orden}")
        print(f"AIC: {mejor_aic:.2f}")
        print("Interpretación:")
        print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
        print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar modelos ARMA
goog_orden = find_best_arma(goog_close, "3MIN 3D GOOG")
ko_orden = find_best_arma(ko_close, "3MIN 3D KO")

goog_modelo = ARIMA(goog_close, order=goog_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronóstico
pasos_pronostico = 30
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Graficar
ultimo_indice = len(goog_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

plt.figure(figsize=(12,6))
plt.plot(goog_close, label='Histórico 3MIN 3D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 3MIN 3D GOOG', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D GOOG y 3MIN 3D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")

plot_forecast(goog_modelo, goog_close, "3MIN 3D GOOG")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (5).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (6).xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Se encontró ' Close' en ambos DataFrames, usándola para precios de cierre
Resumen de datos GOOG Close: count    459.000000
mean     173.351168
std        1.840287
min      167.890000
25%      172.395000
50%      173.800000
75%      174.532500
max      176.580000
Name:  Close, dtype: float64
Resumen de datos KO Close: count    459.000000
mean      70.521504
std        0.674861
min       69.511600
25%       70.067500
50%       70.440000
75%       70.747500
max       72.500000
Name:  Close, dtype: float64

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -0.8569
p-valor: 0.8018
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.6762
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D GOOG es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.3740
p-valor: 0.9143
Valores críticos: {'1%': -3.4447721346720885, '5%': -2.8678991615065095, '10%': -2.570157193174823}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.9208
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [13.92472228  0.16259597]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
  - r = 1: No hay cointegración al 95% de confianza
Conclusión: No hay evidencia de cointegración entre GOOG y KO
<ipython-input-20-1ab4b7a8e033>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-20-1ab4b7a8e033>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 3)
AIC: 231.65
Interpretación:
  - p=3: 3 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (3, 0, 0)
AIC: -971.72
Interpretación:
  - p=3: 3 término(s) autorregresivo(s)
  - q=0: 0 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D GOOG:
Último valor observado: 168.73
Valor promedio del pronóstico: 169.29
Cambio en el pronóstico: 0.56
Tendencia: Pronóstico al alza
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D KO:
Último valor observado: 72.15
Valor promedio del pronóstico: 72.15
Cambio en el pronóstico: 0.00
Tendencia: Pronóstico al alza

Valores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):
459    168.936815
460    168.683958
461    168.793214
462    169.041571
463    168.841400
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
459    72.182067
460    72.171349
461    72.167391
462    72.167603
463    72.166584
Name: predicted_mean, dtype: float64
In [21]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    goog_close = goog_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')

# Realizar pruebas de raíz unitaria
unit_root_tests(goog_close, "3MIN 3D GOOG")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"r = {i}: No hay cointegración al 95% de confianza")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'GOOG': goog_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
goog_orden = find_best_arma(goog_close, "3MIN 3D GOOG")
ko_orden = find_best_arma(ko_close, "3MIN 3D KO")

goog_modelo = ARIMA(goog_close, order=goog_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(goog_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(goog_close, label='Histórico 3MIN 3D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 3MIN 3D GOOG', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D GOOG y 3MIN 3D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

# Generar gráficos de pronóstico detallados
plot_forecast(goog_modelo, goog_close, "3MIN 3D GOOG")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (6).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (7).xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -0.8569
p-valor: 0.8018
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}

Prueba KPSS:
Estadístico KPSS: 1.6762
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.3740
p-valor: 0.9143
Valores críticos: {'1%': -3.4447721346720885, '5%': -2.8678991615065095, '10%': -2.570157193174823}

Prueba KPSS:
Estadístico KPSS: 0.9208
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Prueba de cointegración de Johansen:
Estadístico de traza: [13.92472228  0.16259597]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
r = 0: No hay cointegración al 95% de confianza
r = 1: No hay cointegración al 95% de confianza
<ipython-input-21-eb3a0b48f125>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-21-eb3a0b48f125>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 3)
AIC: 231.65
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (3, 0, 0)
AIC: -971.72
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Valores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):
459    168.936815
460    168.683958
461    168.793214
462    169.041571
463    168.841400
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
459    72.182067
460    72.171349
461    72.167391
462    72.167603
463    72.166584
Name: predicted_mean, dtype: float64
In [22]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    goog_close = goog_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria con interpretación
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

# Realizar pruebas de raíz unitaria
unit_root_tests(goog_close, "3MIN 3D GOOG")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración con interpretación
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) > valor crítico 95% ({result.cvt[i, 1]:.2f})")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) <= valor crítico 95% ({result.cvt[i, 1]:.2f})")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: GOOG y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre GOOG y KO")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'GOOG': goog_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA con interpretación
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    print("Interpretación:")
    print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
    print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
goog_orden = find_best_arma(goog_close, "3MIN 3D GOOG")
ko_orden = find_best_arma(ko_close, "3MIN 3D KO")

goog_modelo = ARIMA(goog_close, order=goog_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(goog_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(goog_close, label='Histórico 3MIN 3D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 3MIN 3D GOOG', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D GOOG y 3MIN 3D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza e interpretación
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")
    print(f"Rango del intervalo de confianza 95% en el período {steps}: [{intervalo_conf.iloc[-1, 0]:.2f}, {intervalo_conf.iloc[-1, 1]:.2f}]")

# Generar gráficos de pronóstico detallados e interpretaciones
plot_forecast(goog_modelo, goog_close, "3MIN 3D GOOG")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (7).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (8).xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -0.8569
p-valor: 0.8018
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.6762
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D GOOG es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.3740
p-valor: 0.9143
Valores críticos: {'1%': -3.4447721346720885, '5%': -2.8678991615065095, '10%': -2.570157193174823}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.9208
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [13.92472228  0.16259597]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
    Estadístico de traza (13.92) <= valor crítico 95% (15.49)
  - r = 1: No hay cointegración al 95% de confianza
    Estadístico de traza (0.16) <= valor crítico 95% (3.84)
Conclusión: No hay evidencia de cointegración entre GOOG y KO
<ipython-input-22-dc7cfd7b393a>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-22-dc7cfd7b393a>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 3)
AIC: 231.65
Interpretación:
  - p=3: 3 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (3, 0, 0)
AIC: -971.72
Interpretación:
  - p=3: 3 término(s) autorregresivo(s)
  - q=0: 0 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D GOOG:
Último valor observado: 168.73
Valor promedio del pronóstico: 169.29
Cambio en el pronóstico: 0.56
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [166.85, 172.61]
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D KO:
Último valor observado: 72.15
Valor promedio del pronóstico: 72.15
Cambio en el pronóstico: 0.00
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [71.43, 72.85]

Valores de pronóstico de 3MIN 3D GOOG (próximos 5 períodos):
459    168.936815
460    168.683958
461    168.793214
462    169.041571
463    168.841400
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
459    72.182067
460    72.171349
461    72.167391
462    72.167603
463    72.166584
Name: predicted_mean, dtype: float64
In [23]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    goog_close = goog_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud y eliminar valores nulos
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud].dropna()
ko_close = ko_close[:min_longitud].dropna()

# Paso 1: Determinar tendencia y estacionalidad
def plot_trend_seasonality(series, name):
    plt.figure(figsize=(12, 6))
    plt.plot(series, label=f'Precios {name}')
    plt.title(f'Precios de cierre de {name}')
    plt.legend()
    plt.show()

    # Descomposición (período 30 para datos de 3 minutos, ajustar si es necesario)
    decomposition = seasonal_decompose(series, model='additive', period=30)
    tendencia = decomposition.trend
    estacionalidad = decomposition.seasonal
    residuo = decomposition.resid

    plt.figure(figsize=(12, 8))
    plt.subplot(411)
    plt.plot(series, label='Original')
    plt.legend(loc='upper left')
    plt.subplot(412)
    plt.plot(tendencia, label='Tendencia')
    plt.legend(loc='upper left')
    plt.subplot(413)
    plt.plot(estacionalidad, label='Estacionalidad')
    plt.legend(loc='upper left')
    plt.subplot(414)
    plt.plot(residuo, label='Residuos')
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()

    print(f"\nAnálisis para {name}:")
    print("- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.")
    print("- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.")

plot_trend_seasonality(goog_close, "3MIN 3D GOOG")
plot_trend_seasonality(ko_close, "3MIN 3D KO")

# Paso 2: Determinar si los datos son estacionarios
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(goog_close, "3MIN 3D GOOG")
unit_root_tests(ko_close, "3MIN 3D KO")

# Paso 3: Dividir datos en entrenamiento (90%) y prueba (10%)
tamano_entrenamiento = int(len(goog_close) * 0.9)
goog_entrenamiento, goog_prueba = goog_close[:tamano_entrenamiento], goog_close[tamano_entrenamiento:]
ko_entrenamiento, ko_prueba = ko_close[:tamano_entrenamiento], ko_close[tamano_entrenamiento:]

print(f"\nDivisión de datos:")
print(f"GOOG - Tamaño entrenamiento: {len(goog_entrenamiento)}, Tamaño prueba: {len(goog_prueba)}")
print(f"KO - Tamaño entrenamiento: {len(ko_entrenamiento)}, Tamaño prueba: {len(ko_prueba)}")

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA en datos de entrenamiento
goog_orden = find_best_arma(goog_entrenamiento, "3MIN 3D GOOG")
ko_orden = find_best_arma(ko_entrenamiento, "3MIN 3D KO")

goog_modelo = ARIMA(goog_entrenamiento, order=goog_orden).fit()
ko_modelo = ARIMA(ko_entrenamiento, order=ko_orden).fit()

# Pronosticar para el período de prueba
pasos_prueba = len(goog_prueba)
goog_pronostico = goog_modelo.forecast(steps=pasos_prueba)
ko_pronostico = ko_modelo.forecast(steps=pasos_prueba)

# Graficar entrenamiento, prueba y pronóstico
def plot_train_test_forecast(entrenamiento, prueba, pronostico, name):
    indice_pronostico = range(len(entrenamiento), len(entrenamiento) + len(prueba))
    plt.figure(figsize=(12, 6))
    plt.plot(entrenamiento, label=f'{name} Entrenamiento')
    plt.plot(range(len(entrenamiento), len(entrenamiento) + len(prueba)), prueba, label=f'{name} Prueba')
    plt.plot(indice_pronostico, pronostico, label=f'{name} Pronóstico', color='red')
    plt.title(f'{name} Entrenamiento, Prueba y Pronóstico')
    plt.legend()
    plt.show()

plot_train_test_forecast(goog_entrenamiento, goog_prueba, goog_pronostico, "3MIN 3D GOOG")
plot_train_test_forecast(ko_entrenamiento, ko_prueba, ko_pronostico, "3MIN 3D KO")

# Evaluar precisión del pronóstico
goog_mse = mean_squared_error(goog_prueba, goog_pronostico)
ko_mse = mean_squared_error(ko_prueba, ko_pronostico)
print(f"\nPrecisión del pronóstico:")
print(f"GOOG Error cuadrático medio: {goog_mse:.2f}")
print(f"KO Error cuadrático medio: {ko_mse:.2f}")
Por favor, sube el archivo Excel de 3MIN 3D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D GOOG.xlsx to 3MIN 3D GOOG (8).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (9).xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close
No description has been provided for this image
No description has been provided for this image
Análisis para 3MIN 3D GOOG:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.
No description has been provided for this image
No description has been provided for this image
Análisis para 3MIN 3D KO:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.

Pruebas de raíz unitaria para 3MIN 3D GOOG:
Prueba ADF:
Estadístico ADF: -0.8569
p-valor: 0.8018
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.6762
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D GOOG es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.3740
p-valor: 0.9143
Valores críticos: {'1%': -3.4447721346720885, '5%': -2.8678991615065095, '10%': -2.570157193174823}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.9208
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

División de datos:
GOOG - Tamaño entrenamiento: 413, Tamaño prueba: 46
KO - Tamaño entrenamiento: 413, Tamaño prueba: 46
<ipython-input-23-72e5c78dd23f>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-23-72e5c78dd23f>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D GOOG:
Orden: (3, 0, 3)
AIC: 178.39
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (2, 0, 2)
AIC: -928.89
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Precisión del pronóstico:
GOOG Error cuadrático medio: 11.54
KO Error cuadrático medio: 0.83
In [1]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Verificar columna " Close"
columna_esperada = " Close"
if columna_esperada in pep_df.columns and columna_esperada in ko_df.columns:
    columna_cierre = columna_esperada
    print(f"Se encontró '{columna_esperada}' en ambos DataFrames, usándola para precios de cierre")
else:
    while True:
        columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ").strip()
        if columna_cierre in pep_df.columns and columna_cierre in ko_df.columns:
            break
        else:
            print(f"Error: '{columna_cierre}' no encontrada en uno o ambos DataFrames")

# Extraer y limpiar precios de cierre
pep_close = pep_df[columna_cierre].dropna()
ko_close = ko_df[columna_cierre].dropna()

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Verificación de datos
print("Resumen de datos PEP Close:", pep_close.describe())
print("Resumen de datos KO Close:", ko_close.describe())
if len(pep_close) < 10:
    raise ValueError("Datos insuficientes para PEP")

# Pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")

    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: PEP y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre PEP y KO")

coint_df = pd.DataFrame({'PEP': pep_close, 'KO': ko_close})
cointegration_test(coint_df)

# Función ARIMA actualizada
def find_best_arima(series, name, max_p=3, max_d=2, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for d in range(max_d + 1):
            for q in range(max_q + 1):
                try:
                    modelo = ARIMA(series, order=(p, d, q))
                    resultados = modelo.fit()
                    if resultados.aic < mejor_aic:
                        mejor_aic = resultados.aic
                        mejor_orden = (p, d, q)
                except Exception as e:
                    print(f"No se pudo ajustar ARIMA({p},{d},{q}) para {name}: {str(e)}")
                    continue

    if mejor_orden is None:
        print(f"Advertencia: No se encontró un modelo ARIMA válido para {name}. Usando predeterminado (1,1,1)")
        mejor_orden = (1, 1, 1)
        mejor_aic = float('inf')
    else:
        print(f"\nMejor modelo ARIMA para {name}:")
        print(f"Orden: {mejor_orden}")
        print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar modelos ARIMA
pep_orden = find_best_arima(pep_close, "3MIN 3D PEP")
ko_orden = find_best_arima(ko_close, "3MIN 3D KO")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronóstico
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Graficar
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 3MIN 3D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 3MIN 3D PEP', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D PEP y 3MIN 3D KO con pronósticos')
plt.legend()
plt.show()

# Graficar pronóstico detallado
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")

plot_forecast(pep_modelo, pep_close, "3MIN 3D PEP")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP.xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO.xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Se encontró ' Close' en ambos DataFrames, usándola para precios de cierre
Resumen de datos PEP Close: count    455.000000
mean     155.048004
std        1.622073
min      152.610000
25%      154.070000
50%      154.580000
75%      155.972500
max      159.895000
Name:  Close, dtype: float64
Resumen de datos KO Close: count    455.000000
mean      70.505891
std        0.656618
min       69.511600
25%       70.060000
50%       70.440000
75%       70.727500
max       72.475000
Name:  Close, dtype: float64

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D PEP es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
<ipython-input-1-dfb383ab4830>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-1-dfb383ab4830>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
Prueba ADF:
Estadístico ADF: -0.1656
p-valor: 0.9425
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.8621
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [41.01834549  1.55323179]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: Existe cointegración al 95% de confianza
  - r = 1: No hay cointegración al 95% de confianza
Conclusión: PEP y KO están cointegrados - comparten una relación de equilibrio a largo plazo
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARIMA para 3MIN 3D PEP:
Orden: (3, 1, 3)
AIC: -106.54
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARIMA para 3MIN 3D KO:
Orden: (3, 1, 3)
AIC: -989.02
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D PEP:
Último valor observado: 157.35
Valor promedio del pronóstico: 157.27
Cambio en el pronóstico: -0.08
Tendencia: Pronóstico a la baja
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D KO:
Último valor observado: 72.28
Valor promedio del pronóstico: 72.25
Cambio en el pronóstico: -0.03
Tendencia: Pronóstico a la baja

Valores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):
455    157.413165
456    157.421383
457    157.314766
458    157.251448
459    157.184305
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
455    72.266008
456    72.272477
457    72.256501
458    72.261430
459    72.247765
Name: predicted_mean, dtype: float64
In [2]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Verificar columna " Close"
columna_esperada = " Close"
if columna_esperada in pep_df.columns and columna_esperada in ko_df.columns:
    columna_cierre = columna_esperada
    print(f"Se encontró '{columna_esperada}' en ambos DataFrames, usándola para precios de cierre")
else:
    while True:
        columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ").strip()
        if columna_cierre in pep_df.columns and columna_cierre in ko_df.columns:
            break
        else:
            print(f"Error: '{columna_cierre}' no encontrada en uno o ambos DataFrames")

# Extraer y limpiar precios de cierre
pep_close = pep_df[columna_cierre].dropna()
ko_close = ko_df[columna_cierre].dropna()

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Verificación de datos
print("Resumen de datos PEP Close:", pep_close.describe())
print("Resumen de datos KO Close:", ko_close.describe())
if len(pep_close) < 10:
    raise ValueError("Datos insuficientes para PEP")

# Pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")

    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: PEP y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre PEP y KO")

coint_df = pd.DataFrame({'PEP': pep_close, 'KO': ko_close})
cointegration_test(coint_df)

# Función ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except Exception as e:
                print(f"No se pudo ajustar ARMA({p},{q}) para {name}: {str(e)}")
                continue

    if mejor_orden is None:
        print(f"Advertencia: No se encontró un modelo ARMA válido para {name}. Usando predeterminado (1,0,1)")
        mejor_orden = (1, 0, 1)
        mejor_aic = float('inf')
    else:
        print(f"\nMejor modelo ARMA para {name}:")
        print(f"Orden: {mejor_orden}")
        print(f"AIC: {mejor_aic:.2f}")
        print("Interpretación:")
        print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
        print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar modelos ARMA
pep_orden = find_best_arma(pep_close, "3MIN 3D PEP")
ko_orden = find_best_arma(ko_close, "3MIN 3D KO")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronóstico
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Graficar
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 3MIN 3D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 3MIN 3D PEP', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D PEP y 3MIN 3D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")

plot_forecast(pep_modelo, pep_close, "3MIN 3D PEP")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (1).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (1).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Se encontró ' Close' en ambos DataFrames, usándola para precios de cierre
Resumen de datos PEP Close: count    455.000000
mean     155.048004
std        1.622073
min      152.610000
25%      154.070000
50%      154.580000
75%      155.972500
max      159.895000
Name:  Close, dtype: float64
Resumen de datos KO Close: count    455.000000
mean      70.505891
std        0.656618
min       69.511600
25%       70.060000
50%       70.440000
75%       70.727500
max       72.475000
Name:  Close, dtype: float64

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D PEP es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.1656
p-valor: 0.9425
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.8621
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [41.01834549  1.55323179]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: Existe cointegración al 95% de confianza
  - r = 1: No hay cointegración al 95% de confianza
Conclusión: PEP y KO están cointegrados - comparten una relación de equilibrio a largo plazo
<ipython-input-2-2ed56c6a7a46>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-2-2ed56c6a7a46>:67: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -99.05
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (2, 0, 3)
AIC: -986.21
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D PEP:
Último valor observado: 157.35
Valor promedio del pronóstico: 157.26
Cambio en el pronóstico: -0.09
Tendencia: Pronóstico a la baja
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D KO:
Último valor observado: 72.28
Valor promedio del pronóstico: 72.36
Cambio en el pronóstico: 0.08
Tendencia: Pronóstico al alza

Valores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):
455    157.329568
456    157.328138
457    157.302106
458    157.317722
459    157.295289
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
455    72.291555
456    72.300087
457    72.307797
458    72.315059
459    72.321886
Name: predicted_mean, dtype: float64
In [3]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"r = {i}: No hay cointegración al 95% de confianza")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "3MIN 3D PEP")
ko_orden = find_best_arma(ko_close, "3MIN 3D KO")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 3MIN 3D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 3MIN 3D PEP', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D PEP y 3MIN 3D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

# Generar gráficos de pronóstico detallados
plot_forecast(pep_modelo, pep_close, "3MIN 3D PEP")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (2).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (2).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.1656
p-valor: 0.9425
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}

Prueba KPSS:
Estadístico KPSS: 0.8621
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Prueba de cointegración de Johansen:
Estadístico de traza: [41.01834549  1.55323179]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
r = 0: Existe cointegración al 95% de confianza
r = 1: No hay cointegración al 95% de confianza
<ipython-input-3-ffa8c05b5852>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-3-ffa8c05b5852>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -99.05
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (2, 0, 3)
AIC: -986.21
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Valores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):
455    157.329568
456    157.328138
457    157.302106
458    157.317722
459    157.295289
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
455    72.291555
456    72.300087
457    72.307797
458    72.315059
459    72.321886
Name: predicted_mean, dtype: float64
In [4]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria con interpretación
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(ko_close, "3MIN 3D KO")

# Prueba de cointegración con interpretación
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) > valor crítico 95% ({result.cvt[i, 1]:.2f})")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) <= valor crítico 95% ({result.cvt[i, 1]:.2f})")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: PEP y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre PEP y KO")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA con interpretación
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    print("Interpretación:")
    print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
    print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "3MIN 3D PEP")
ko_orden = find_best_arma(ko_close, "3MIN 3D KO")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 3MIN 3D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 3MIN 3D PEP', color='red')
plt.plot(ko_close, label='Histórico 3MIN 3D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 3MIN 3D KO', color='green')
plt.title('Precios de cierre de 3MIN 3D PEP y 3MIN 3D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza e interpretación
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")
    print(f"Rango del intervalo de confianza 95% en el período {steps}: [{intervalo_conf.iloc[-1, 0]:.2f}, {intervalo_conf.iloc[-1, 1]:.2f}]")

# Generar gráficos de pronóstico detallados e interpretaciones
plot_forecast(pep_modelo, pep_close, "3MIN 3D PEP")
plot_forecast(ko_modelo, ko_close, "3MIN 3D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 3MIN 3D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (3).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (3).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D PEP es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.1656
p-valor: 0.9425
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.8621
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [41.01834549  1.55323179]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: Existe cointegración al 95% de confianza
    Estadístico de traza (41.02) > valor crítico 95% (15.49)
  - r = 1: No hay cointegración al 95% de confianza
    Estadístico de traza (1.55) <= valor crítico 95% (3.84)
Conclusión: PEP y KO están cointegrados - comparten una relación de equilibrio a largo plazo
<ipython-input-4-972a35d6da0e>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-4-972a35d6da0e>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -99.05
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (2, 0, 3)
AIC: -986.21
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=3: 3 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D PEP:
Último valor observado: 157.35
Valor promedio del pronóstico: 157.26
Cambio en el pronóstico: -0.09
Tendencia: Pronóstico a la baja
Rango del intervalo de confianza 95% en el período 30: [155.52, 158.89]
No description has been provided for this image
Interpretación del pronóstico para 3MIN 3D KO:
Último valor observado: 72.28
Valor promedio del pronóstico: 72.36
Cambio en el pronóstico: 0.08
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [71.54, 73.22]

Valores de pronóstico de 3MIN 3D PEP (próximos 5 períodos):
455    157.329568
456    157.328138
457    157.302106
458    157.317722
459    157.295289
Name: predicted_mean, dtype: float64

Valores de pronóstico de 3MIN 3D KO (próximos 5 períodos):
455    72.291555
456    72.300087
457    72.307797
458    72.315059
459    72.321886
Name: predicted_mean, dtype: float64
In [5]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 3MIN 3D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 3MIN 3D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud y eliminar valores nulos
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud].dropna()
ko_close = ko_close[:min_longitud].dropna()

# Paso 1: Determinar tendencia y estacionalidad
def plot_trend_seasonality(series, name):
    plt.figure(figsize=(12, 6))
    plt.plot(series, label=f'Precios {name}')
    plt.title(f'Precios de cierre de {name}')
    plt.legend()
    plt.show()

    # Descomposición (período 30 para datos de 3 minutos, ajustar si es necesario)
    decomposition = seasonal_decompose(series, model='additive', period=30)
    tendencia = decomposition.trend
    estacionalidad = decomposition.seasonal
    residuo = decomposition.resid

    plt.figure(figsize=(12, 8))
    plt.subplot(411)
    plt.plot(series, label='Original')
    plt.legend(loc='upper left')
    plt.subplot(412)
    plt.plot(tendencia, label='Tendencia')
    plt.legend(loc='upper left')
    plt.subplot(413)
    plt.plot(estacionalidad, label='Estacionalidad')
    plt.legend(loc='upper left')
    plt.subplot(414)
    plt.plot(residuo, label='Residuos')
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()

    print(f"\nAnálisis para {name}:")
    print("- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.")
    print("- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.")

plot_trend_seasonality(pep_close, "3MIN 3D PEP")
plot_trend_seasonality(ko_close, "3MIN 3D KO")

# Paso 2: Determinar si los datos son estacionarios
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(pep_close, "3MIN 3D PEP")
unit_root_tests(ko_close, "3MIN 3D KO")

# Paso 3: Dividir datos en entrenamiento (90%) y prueba (10%)
tamano_entrenamiento = int(len(pep_close) * 0.9)
pep_entrenamiento, pep_prueba = pep_close[:tamano_entrenamiento], pep_close[tamano_entrenamiento:]
ko_entrenamiento, ko_prueba = ko_close[:tamano_entrenamiento], ko_close[tamano_entrenamiento:]

print(f"\nDivisión de datos:")
print(f"PEP - Tamaño entrenamiento: {len(pep_entrenamiento)}, Tamaño prueba: {len(pep_prueba)}")
print(f"KO - Tamaño entrenamiento: {len(ko_entrenamiento)}, Tamaño prueba: {len(ko_prueba)}")

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA en datos de entrenamiento
pep_orden = find_best_arma(pep_entrenamiento, "3MIN 3D PEP")
ko_orden = find_best_arma(ko_entrenamiento, "3MIN 3D KO")

pep_modelo = ARIMA(pep_entrenamiento, order=pep_orden).fit()
ko_modelo = ARIMA(ko_entrenamiento, order=ko_orden).fit()

# Pronosticar para el período de prueba
pasos_prueba = len(pep_prueba)
pep_pronostico = pep_modelo.forecast(steps=pasos_prueba)
ko_pronostico = ko_modelo.forecast(steps=pasos_prueba)

# Graficar entrenamiento, prueba y pronóstico
def plot_train_test_forecast(entrenamiento, prueba, pronostico, name):
    indice_pronostico = range(len(entrenamiento), len(entrenamiento) + len(prueba))
    plt.figure(figsize=(12, 6))
    plt.plot(entrenamiento, label=f'{name} Entrenamiento')
    plt.plot(range(len(entrenamiento), len(entrenamiento) + len(prueba)), prueba, label=f'{name} Prueba')
    plt.plot(indice_pronostico, pronostico, label=f'{name} Pronóstico', color='red')
    plt.title(f'{name} Entrenamiento, Prueba y Pronóstico')
    plt.legend()
    plt.show()

plot_train_test_forecast(pep_entrenamiento, pep_prueba, pep_pronostico, "3MIN 3D PEP")
plot_train_test_forecast(ko_entrenamiento, ko_prueba, ko_pronostico, "3MIN 3D KO")

# Evaluar precisión del pronóstico
pep_mse = mean_squared_error(pep_prueba, pep_pronostico)
ko_mse = mean_squared_error(ko_prueba, ko_pronostico)
print(f"\nPrecisión del pronóstico:")
print(f"PEP Error cuadrático medio: {pep_mse:.2f}")
print(f"KO Error cuadrático medio: {ko_mse:.2f}")
Por favor, sube el archivo Excel de 3MIN 3D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D PEP.xlsx to 3MIN 3D PEP (4).xlsx
Por favor, sube el archivo Excel de 3MIN 3D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 3MIN 3D KO.xlsx to 3MIN 3D KO (4).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close
No description has been provided for this image
No description has been provided for this image
Análisis para 3MIN 3D PEP:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.
No description has been provided for this image
No description has been provided for this image
Análisis para 3MIN 3D KO:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.

Pruebas de raíz unitaria para 3MIN 3D PEP:
Prueba ADF:
Estadístico ADF: -1.4332
p-valor: 0.5662
Valores críticos: {'1%': -3.4452655826028318, '5%': -2.868116205869215, '10%': -2.570272878944473}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.3351
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D PEP es no estacionario

Pruebas de raíz unitaria para 3MIN 3D KO:
Prueba ADF:
Estadístico ADF: -0.1656
p-valor: 0.9425
Valores críticos: {'1%': -3.444900499925237, '5%': -2.8679556266351653, '10%': -2.570187288941969}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 3MIN 3D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.8621
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 3MIN 3D KO es no estacionario

División de datos:
PEP - Tamaño entrenamiento: 409, Tamaño prueba: 46
KO - Tamaño entrenamiento: 409, Tamaño prueba: 46
<ipython-input-5-5b0887ced65f>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-5-5b0887ced65f>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 3MIN 3D PEP:
Orden: (2, 0, 3)
AIC: -194.05
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 3MIN 3D KO:
Orden: (2, 0, 2)
AIC: -922.53
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Precisión del pronóstico:
PEP Error cuadrático medio: 2.74
KO Error cuadrático medio: 0.83
In [6]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame GOOG:", list(goog_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    goog_close = goog_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(goog_close))
pep_close = pep_close[:min_longitud]
goog_close = goog_close[:min_longitud]

# Función para pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "30MIN 10D PEP")
unit_root_tests(goog_close, "30MIN 10D GOOG")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"r = {i}: No hay cointegración al 95% de confianza")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'GOOG': goog_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "30MIN 10D PEP")
goog_orden = find_best_arma(goog_close, "30MIN 10D GOOG")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
goog_modelo = ARIMA(goog_close, order=goog_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 30MIN 10D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 30MIN 10D PEP', color='red')
plt.plot(goog_close, label='Histórico 30MIN 10D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 30MIN 10D GOOG', color='green')
plt.title('Precios de cierre de 30MIN 10D PEP y 30MIN 10D GOOG con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

# Generar gráficos de pronóstico detallados
plot_forecast(pep_modelo, pep_close, "30MIN 10D PEP")
plot_forecast(goog_modelo, goog_close, "30MIN 10D GOOG")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
Por favor, sube el archivo Excel de 30MIN 10D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D PEP.xlsx to 30MIN 10D PEP.xlsx
Por favor, sube el archivo Excel de 30MIN 10D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D GOOG.xlsx to 30MIN 10D GOOG.xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 30MIN 10D PEP:
Prueba ADF:
Estadístico ADF: -1.1259
p-valor: 0.7046
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}

Prueba KPSS:
Estadístico KPSS: 0.5461
p-valor: 0.0313
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Pruebas de raíz unitaria para 30MIN 10D GOOG:
Prueba ADF:
Estadístico ADF: -0.1157
p-valor: 0.9479
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}

Prueba KPSS:
Estadístico KPSS: 1.2595
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Prueba de cointegración de Johansen:
Estadístico de traza: [3.48649485 0.00379771]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
r = 0: No hay cointegración al 95% de confianza
r = 1: No hay cointegración al 95% de confianza
<ipython-input-6-3c91b469fd72>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D PEP:
Orden: (1, 0, 0)
AIC: 332.76
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 30MIN 10D GOOG:
Orden: (1, 0, 0)
AIC: 361.47
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Valores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):
150    147.605245
151    147.756244
152    147.903114
153    148.045966
154    148.184912
Name: predicted_mean, dtype: float64

Valores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):
150    185.042134
151    184.974941
152    184.908414
153    184.842546
154    184.777332
Name: predicted_mean, dtype: float64
In [7]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame GOOG:", list(goog_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    goog_close = goog_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(goog_close))
pep_close = pep_close[:min_longitud]
goog_close = goog_close[:min_longitud]

# Función para pruebas de raíz unitaria con interpretación
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "30MIN 10D PEP")
unit_root_tests(goog_close, "30MIN 10D GOOG")

# Prueba de cointegración con interpretación
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) > valor crítico 95% ({result.cvt[i, 1]:.2f})")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) <= valor crítico 95% ({result.cvt[i, 1]:.2f})")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: PEP y GOOG están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre PEP y GOOG")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'GOOG': goog_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA con interpretación
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    print("Interpretación:")
    print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
    print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "30MIN 10D PEP")
goog_orden = find_best_arma(goog_close, "30MIN 10D GOOG")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
goog_modelo = ARIMA(goog_close, order=goog_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 30MIN 10D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 30MIN 10D PEP', color='red')
plt.plot(goog_close, label='Histórico 30MIN 10D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 30MIN 10D GOOG', color='green')
plt.title('Precios de cierre de 30MIN 10D PEP y 30MIN 10D GOOG con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza e interpretación
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")
    print(f"Rango del intervalo de confianza 95% en el período {steps}: [{intervalo_conf.iloc[-1, 0]:.2f}, {intervalo_conf.iloc[-1, 1]:.2f}]")

# Generar gráficos de pronóstico detallados e interpretaciones
plot_forecast(pep_modelo, pep_close, "30MIN 10D PEP")
plot_forecast(goog_modelo, goog_close, "30MIN 10D GOOG")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
Por favor, sube el archivo Excel de 30MIN 10D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D PEP.xlsx to 30MIN 10D PEP (1).xlsx
Por favor, sube el archivo Excel de 30MIN 10D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D GOOG.xlsx to 30MIN 10D GOOG (1).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 30MIN 10D PEP:
Prueba ADF:
Estadístico ADF: -1.1259
p-valor: 0.7046
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.5461
p-valor: 0.0313
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D PEP es no estacionario

Pruebas de raíz unitaria para 30MIN 10D GOOG:
Prueba ADF:
Estadístico ADF: -0.1157
p-valor: 0.9479
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.2595
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D GOOG es no estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [3.48649485 0.00379771]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
    Estadístico de traza (3.49) <= valor crítico 95% (15.49)
  - r = 1: No hay cointegración al 95% de confianza
    Estadístico de traza (0.00) <= valor crítico 95% (3.84)
Conclusión: No hay evidencia de cointegración entre PEP y GOOG
<ipython-input-7-7aa134bac5a1>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D PEP:
Orden: (1, 0, 0)
AIC: 332.76
Interpretación:
  - p=1: 1 término(s) autorregresivo(s)
  - q=0: 0 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 30MIN 10D GOOG:
Orden: (1, 0, 0)
AIC: 361.47
Interpretación:
  - p=1: 1 término(s) autorregresivo(s)
  - q=0: 0 término(s) de media móvil
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 30MIN 10D PEP:
Último valor observado: 147.45
Valor promedio del pronóstico: 149.33
Cambio en el pronóstico: 1.88
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [145.25, 156.07]
No description has been provided for this image
Interpretación del pronóstico para 30MIN 10D GOOG:
Último valor observado: 185.11
Valor promedio del pronóstico: 184.15
Cambio en el pronóstico: -0.96
Tendencia: Pronóstico a la baja
Rango del intervalo de confianza 95% en el período 30: [176.03, 190.65]

Valores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):
150    147.605245
151    147.756244
152    147.903114
153    148.045966
154    148.184912
Name: predicted_mean, dtype: float64

Valores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):
150    185.042134
151    184.974941
152    184.908414
153    184.842546
154    184.777332
Name: predicted_mean, dtype: float64
In [8]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame GOOG:", list(goog_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    goog_close = goog_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud y eliminar valores nulos
min_longitud = min(len(pep_close), len(goog_close))
pep_close = pep_close[:min_longitud].dropna()
goog_close = goog_close[:min_longitud].dropna()

# Paso 1: Determinar tendencia y estacionalidad
def plot_trend_seasonality(series, name):
    plt.figure(figsize=(12, 6))
    plt.plot(series, label=f'Precios {name}')
    plt.title(f'Precios de cierre de {name}')
    plt.legend()
    plt.show()

    # Descomposición (período 48 para 30 minutos en 10 días: 48 intervalos por día)
    decomposition = seasonal_decompose(series, model='additive', period=48)
    tendencia = decomposition.trend
    estacionalidad = decomposition.seasonal
    residuo = decomposition.resid

    plt.figure(figsize=(12, 8))
    plt.subplot(411)
    plt.plot(series, label='Original')
    plt.legend(loc='upper left')
    plt.subplot(412)
    plt.plot(tendencia, label='Tendencia')
    plt.legend(loc='upper left')
    plt.subplot(413)
    plt.plot(estacionalidad, label='Estacionalidad')
    plt.legend(loc='upper left')
    plt.subplot(414)
    plt.plot(residuo, label='Residuos')
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()

    print(f"\nAnálisis para {name}:")
    print("- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.")
    print("- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.")

plot_trend_seasonality(pep_close, "30MIN 10D PEP")
plot_trend_seasonality(goog_close, "30MIN 10D GOOG")

# Paso 2: Determinar si los datos son estacionarios
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(pep_close, "30MIN 10D PEP")
unit_root_tests(goog_close, "30MIN 10D GOOG")

# Paso 3: Dividir datos en entrenamiento (90%) y prueba (10%)
tamano_entrenamiento = int(len(pep_close) * 0.9)
pep_entrenamiento, pep_prueba = pep_close[:tamano_entrenamiento], pep_close[tamano_entrenamiento:]
goog_entrenamiento, goog_prueba = goog_close[:tamano_entrenamiento], goog_close[tamano_entrenamiento:]

print(f"\nDivisión de datos:")
print(f"PEP - Tamaño entrenamiento: {len(pep_entrenamiento)}, Tamaño prueba: {len(pep_prueba)}")
print(f"GOOG - Tamaño entrenamiento: {len(goog_entrenamiento)}, Tamaño prueba: {len(goog_prueba)}")

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA en datos de entrenamiento
pep_orden = find_best_arma(pep_entrenamiento, "30MIN 10D PEP")
goog_orden = find_best_arma(goog_entrenamiento, "30MIN 10D GOOG")

pep_modelo = ARIMA(pep_entrenamiento, order=pep_orden).fit()
goog_modelo = ARIMA(goog_entrenamiento, order=goog_orden).fit()

# Pronosticar para el período de prueba
pasos_prueba = len(pep_prueba)
pep_pronostico = pep_modelo.forecast(steps=pasos_prueba)
goog_pronostico = goog_modelo.forecast(steps=pasos_prueba)

# Graficar entrenamiento, prueba y pronóstico
def plot_train_test_forecast(entrenamiento, prueba, pronostico, name):
    indice_pronostico = range(len(entrenamiento), len(entrenamiento) + len(prueba))
    plt.figure(figsize=(12, 6))
    plt.plot(entrenamiento, label=f'{name} Entrenamiento')
    plt.plot(range(len(entrenamiento), len(entrenamiento) + len(prueba)), prueba, label=f'{name} Prueba')
    plt.plot(indice_pronostico, pronostico, label=f'{name} Pronóstico', color='red')
    plt.title(f'{name} Entrenamiento, Prueba y Pronóstico')
    plt.legend()
    plt.show()

plot_train_test_forecast(pep_entrenamiento, pep_prueba, pep_pronostico, "30MIN 10D PEP")
plot_train_test_forecast(goog_entrenamiento, goog_prueba, goog_pronostico, "30MIN 10D GOOG")

# Evaluar precisión del pronóstico
pep_mse = mean_squared_error(pep_prueba, pep_pronostico)
goog_mse = mean_squared_error(goog_prueba, goog_pronostico)
print(f"\nPrecisión del pronóstico:")
print(f"PEP Error cuadrático medio: {pep_mse:.2f}")
print(f"GOOG Error cuadrático medio: {goog_mse:.2f}")
Por favor, sube el archivo Excel de 30MIN 10D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D PEP.xlsx to 30MIN 10D PEP (2).xlsx
Por favor, sube el archivo Excel de 30MIN 10D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D GOOG.xlsx to 30MIN 10D GOOG (2).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close
No description has been provided for this image
No description has been provided for this image
Análisis para 30MIN 10D PEP:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.
No description has been provided for this image
No description has been provided for this image
Análisis para 30MIN 10D GOOG:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.

Pruebas de raíz unitaria para 30MIN 10D PEP:
Prueba ADF:
Estadístico ADF: -1.1259
p-valor: 0.7046
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.5461
p-valor: 0.0313
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D PEP es no estacionario

Pruebas de raíz unitaria para 30MIN 10D GOOG:
Prueba ADF:
Estadístico ADF: -0.1157
p-valor: 0.9479
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.2595
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D GOOG es no estacionario

División de datos:
PEP - Tamaño entrenamiento: 135, Tamaño prueba: 15
GOOG - Tamaño entrenamiento: 135, Tamaño prueba: 15
<ipython-input-8-d1c4d8da2d15>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 30MIN 10D PEP:
Orden: (1, 0, 0)
AIC: 307.78
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
Mejor modelo ARMA para 30MIN 10D GOOG:
Orden: (1, 0, 0)
AIC: 334.68
No description has been provided for this image
No description has been provided for this image
Precisión del pronóstico:
PEP Error cuadrático medio: 10.68
GOOG Error cuadrático medio: 5.22
In [9]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    goog_close = goog_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')

# Realizar pruebas de raíz unitaria
unit_root_tests(goog_close, "30MIN 10D GOOG")
unit_root_tests(ko_close, "30MIN 10D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"r = {i}: No hay cointegración al 95% de confianza")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'GOOG': goog_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
goog_orden = find_best_arma(goog_close, "30MIN 10D GOOG")
ko_orden = find_best_arma(ko_close, "30MIN 10D KO")

goog_modelo = ARIMA(goog_close, order=goog_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(goog_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(goog_close, label='Histórico 30MIN 10D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 30MIN 10D GOOG', color='red')
plt.plot(ko_close, label='Histórico 30MIN 10D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 30MIN 10D KO', color='green')
plt.title('Precios de cierre de 30MIN 10D GOOG y 30MIN 10D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

# Generar gráficos de pronóstico detallados
plot_forecast(goog_modelo, goog_close, "30MIN 10D GOOG")
plot_forecast(ko_modelo, ko_close, "30MIN 10D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
print("\nValores de pronóstico de 30MIN 10D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 30MIN 10D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D GOOG.xlsx to 30MIN 10D GOOG (3).xlsx
Por favor, sube el archivo Excel de 30MIN 10D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D KO.xlsx to 30MIN 10D KO.xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 30MIN 10D GOOG:
Prueba ADF:
Estadístico ADF: -0.1157
p-valor: 0.9479
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}

Prueba KPSS:
Estadístico KPSS: 1.2595
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Pruebas de raíz unitaria para 30MIN 10D KO:
Prueba ADF:
Estadístico ADF: -2.4792
p-valor: 0.1206
Valores críticos: {'1%': -3.4756368462466662, '5%': -2.8814104466172608, '10%': -2.5773652982553568}

Prueba KPSS:
Estadístico KPSS: 0.1797
p-valor: 0.1000
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Prueba de cointegración de Johansen:
Estadístico de traza: [8.68305596 0.31329526]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
r = 0: No hay cointegración al 95% de confianza
r = 1: No hay cointegración al 95% de confianza
<ipython-input-9-dedad98e3e45>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-9-dedad98e3e45>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is greater than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D GOOG:
Orden: (1, 0, 0)
AIC: 361.47
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
Mejor modelo ARMA para 30MIN 10D KO:
Orden: (2, 0, 1)
AIC: -34.51
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Valores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):
150    185.042134
151    184.974941
152    184.908414
153    184.842546
154    184.777332
Name: predicted_mean, dtype: float64

Valores de pronóstico de 30MIN 10D KO (próximos 5 períodos):
150    69.759322
151    69.867988
152    69.984514
153    70.107479
154    70.235438
Name: predicted_mean, dtype: float64
In [10]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    goog_close = goog_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria con interpretación
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

# Realizar pruebas de raíz unitaria
unit_root_tests(goog_close, "30MIN 10D GOOG")
unit_root_tests(ko_close, "30MIN 10D KO")

# Prueba de cointegración con interpretación
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) > valor crítico 95% ({result.cvt[i, 1]:.2f})")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) <= valor crítico 95% ({result.cvt[i, 1]:.2f})")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: GOOG y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre GOOG y KO")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'GOOG': goog_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA con interpretación
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    print("Interpretación:")
    print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
    print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
goog_orden = find_best_arma(goog_close, "30MIN 10D GOOG")
ko_orden = find_best_arma(ko_close, "30MIN 10D KO")

goog_modelo = ARIMA(goog_close, order=goog_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
goog_pronostico = goog_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(goog_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(goog_close, label='Histórico 30MIN 10D GOOG')
plt.plot(indice_pronostico, goog_pronostico, label='Pronóstico 30MIN 10D GOOG', color='red')
plt.plot(ko_close, label='Histórico 30MIN 10D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 30MIN 10D KO', color='green')
plt.title('Precios de cierre de 30MIN 10D GOOG y 30MIN 10D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza e interpretación
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")
    print(f"Rango del intervalo de confianza 95% en el período {steps}: [{intervalo_conf.iloc[-1, 0]:.2f}, {intervalo_conf.iloc[-1, 1]:.2f}]")

# Generar gráficos de pronóstico detallados e interpretaciones
plot_forecast(goog_modelo, goog_close, "30MIN 10D GOOG")
plot_forecast(ko_modelo, ko_close, "30MIN 10D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):")
print(goog_pronostico[:5])
print("\nValores de pronóstico de 30MIN 10D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 30MIN 10D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D GOOG.xlsx to 30MIN 10D GOOG (4).xlsx
Por favor, sube el archivo Excel de 30MIN 10D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D KO.xlsx to 30MIN 10D KO (1).xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 30MIN 10D GOOG:
Prueba ADF:
Estadístico ADF: -0.1157
p-valor: 0.9479
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.2595
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D GOOG es no estacionario

Pruebas de raíz unitaria para 30MIN 10D KO:
Prueba ADF:
Estadístico ADF: -2.4792
p-valor: 0.1206
Valores críticos: {'1%': -3.4756368462466662, '5%': -2.8814104466172608, '10%': -2.5773652982553568}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.1797
p-valor: 0.1000
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [8.68305596 0.31329526]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
    Estadístico de traza (8.68) <= valor crítico 95% (15.49)
  - r = 1: No hay cointegración al 95% de confianza
    Estadístico de traza (0.31) <= valor crítico 95% (3.84)
Conclusión: No hay evidencia de cointegración entre GOOG y KO
<ipython-input-10-3a2eed4921f4>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-10-3a2eed4921f4>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is greater than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D GOOG:
Orden: (1, 0, 0)
AIC: 361.47
Interpretación:
  - p=1: 1 término(s) autorregresivo(s)
  - q=0: 0 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
Mejor modelo ARMA para 30MIN 10D KO:
Orden: (2, 0, 1)
AIC: -34.51
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=1: 1 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 30MIN 10D GOOG:
Último valor observado: 185.11
Valor promedio del pronóstico: 184.15
Cambio en el pronóstico: -0.96
Tendencia: Pronóstico a la baja
Rango del intervalo de confianza 95% en el período 30: [176.03, 190.65]
No description has been provided for this image
Interpretación del pronóstico para 30MIN 10D KO:
Último valor observado: 69.66
Valor promedio del pronóstico: 71.25
Cambio en el pronóstico: 1.59
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [70.57, 73.10]

Valores de pronóstico de 30MIN 10D GOOG (próximos 5 períodos):
150    185.042134
151    184.974941
152    184.908414
153    184.842546
154    184.777332
Name: predicted_mean, dtype: float64

Valores de pronóstico de 30MIN 10D KO (próximos 5 períodos):
150    69.759322
151    69.867988
152    69.984514
153    70.107479
154    70.235438
Name: predicted_mean, dtype: float64
In [11]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D GOOG")
goog_upload = files.upload()
goog_filename = list(goog_upload.keys())[0]
goog_df = pd.read_excel(goog_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame GOOG:", list(goog_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    goog_close = goog_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud y eliminar valores nulos
min_longitud = min(len(goog_close), len(ko_close))
goog_close = goog_close[:min_longitud].dropna()
ko_close = ko_close[:min_longitud].dropna()

# Paso 1: Determinar tendencia y estacionalidad
def plot_trend_seasonality(series, name):
    plt.figure(figsize=(12, 6))
    plt.plot(series, label=f'Precios {name}')
    plt.title(f'Precios de cierre de {name}')
    plt.legend()
    plt.show()

    # Descomposición (período 48 para 30 minutos en 10 días: 48 intervalos por día)
    decomposition = seasonal_decompose(series, model='additive', period=48)
    tendencia = decomposition.trend
    estacionalidad = decomposition.seasonal
    residuo = decomposition.resid

    plt.figure(figsize=(12, 8))
    plt.subplot(411)
    plt.plot(series, label='Original')
    plt.legend(loc='upper left')
    plt.subplot(412)
    plt.plot(tendencia, label='Tendencia')
    plt.legend(loc='upper left')
    plt.subplot(413)
    plt.plot(estacionalidad, label='Estacionalidad')
    plt.legend(loc='upper left')
    plt.subplot(414)
    plt.plot(residuo, label='Residuos')
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()

    print(f"\nAnálisis para {name}:")
    print("- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.")
    print("- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.")

plot_trend_seasonality(goog_close, "30MIN 10D GOOG")
plot_trend_seasonality(ko_close, "30MIN 10D KO")

# Paso 2: Determinar si los datos son estacionarios
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(goog_close, "30MIN 10D GOOG")
unit_root_tests(ko_close, "30MIN 10D KO")

# Paso 3: Dividir datos en entrenamiento (90%) y prueba (10%)
tamano_entrenamiento = int(len(goog_close) * 0.9)
goog_entrenamiento, goog_prueba = goog_close[:tamano_entrenamiento], goog_close[tamano_entrenamiento:]
ko_entrenamiento, ko_prueba = ko_close[:tamano_entrenamiento], ko_close[tamano_entrenamiento:]

print(f"\nDivisión de datos:")
print(f"GOOG - Tamaño entrenamiento: {len(goog_entrenamiento)}, Tamaño prueba: {len(goog_prueba)}")
print(f"KO - Tamaño entrenamiento: {len(ko_entrenamiento)}, Tamaño prueba: {len(ko_prueba)}")

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA en datos de entrenamiento
goog_orden = find_best_arma(goog_entrenamiento, "30MIN 10D GOOG")
ko_orden = find_best_arma(ko_entrenamiento, "30MIN 10D KO")

goog_modelo = ARIMA(goog_entrenamiento, order=goog_orden).fit()
ko_modelo = ARIMA(ko_entrenamiento, order=ko_orden).fit()

# Pronosticar para el período de prueba
pasos_prueba = len(goog_prueba)
goog_pronostico = goog_modelo.forecast(steps=pasos_prueba)
ko_pronostico = ko_modelo.forecast(steps=pasos_prueba)

# Graficar entrenamiento, prueba y pronóstico
def plot_train_test_forecast(entrenamiento, prueba, pronostico, name):
    indice_pronostico = range(len(entrenamiento), len(entrenamiento) + len(prueba))
    plt.figure(figsize=(12, 6))
    plt.plot(entrenamiento, label=f'{name} Entrenamiento')
    plt.plot(range(len(entrenamiento), len(entrenamiento) + len(prueba)), prueba, label=f'{name} Prueba')
    plt.plot(indice_pronostico, pronostico, label=f'{name} Pronóstico', color='red')
    plt.title(f'{name} Entrenamiento, Prueba y Pronóstico')
    plt.legend()
    plt.show()

plot_train_test_forecast(goog_entrenamiento, goog_prueba, goog_pronostico, "30MIN 10D GOOG")
plot_train_test_forecast(ko_entrenamiento, ko_prueba, ko_pronostico, "30MIN 10D KO")

# Evaluar precisión del pronóstico
goog_mse = mean_squared_error(goog_prueba, goog_pronostico)
ko_mse = mean_squared_error(ko_prueba, ko_pronostico)
print(f"\nPrecisión del pronóstico:")
print(f"GOOG Error cuadrático medio: {goog_mse:.2f}")
print(f"KO Error cuadrático medio: {ko_mse:.2f}")
Por favor, sube el archivo Excel de 30MIN 10D GOOG
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D GOOG.xlsx to 30MIN 10D GOOG (5).xlsx
Por favor, sube el archivo Excel de 30MIN 10D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D KO.xlsx to 30MIN 10D KO (2).xlsx

Columnas del DataFrame GOOG: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close
No description has been provided for this image
No description has been provided for this image
Análisis para 30MIN 10D GOOG:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.
No description has been provided for this image
No description has been provided for this image
Análisis para 30MIN 10D KO:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.

Pruebas de raíz unitaria para 30MIN 10D GOOG:
Prueba ADF:
Estadístico ADF: -0.1157
p-valor: 0.9479
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D GOOG puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 1.2595
p-valor: 0.0100
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D GOOG es no estacionario

Pruebas de raíz unitaria para 30MIN 10D KO:
Prueba ADF:
Estadístico ADF: -2.4792
p-valor: 0.1206
Valores críticos: {'1%': -3.4756368462466662, '5%': -2.8814104466172608, '10%': -2.5773652982553568}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.1797
p-valor: 0.1000
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser estacionario

División de datos:
GOOG - Tamaño entrenamiento: 135, Tamaño prueba: 15
KO - Tamaño entrenamiento: 135, Tamaño prueba: 15
<ipython-input-11-eaac15761937>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is smaller than the p-value returned.

  kpss_result = kpss(series)
<ipython-input-11-eaac15761937>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is greater than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D GOOG:
Orden: (1, 0, 0)
AIC: 334.68
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D KO:
Orden: (2, 0, 1)
AIC: -30.34
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Precisión del pronóstico:
GOOG Error cuadrático medio: 5.22
KO Error cuadrático medio: 1.22
In [12]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "30MIN 10D PEP")
unit_root_tests(ko_close, "30MIN 10D KO")

# Prueba de cointegración
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"r = {i}: Existe cointegración al 95% de confianza")
        else:
            print(f"r = {i}: No hay cointegración al 95% de confianza")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "30MIN 10D PEP")
ko_orden = find_best_arma(ko_close, "30MIN 10D KO")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 30MIN 10D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 30MIN 10D PEP', color='red')
plt.plot(ko_close, label='Histórico 30MIN 10D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 30MIN 10D KO', color='green')
plt.title('Precios de cierre de 30MIN 10D PEP y 30MIN 10D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

# Generar gráficos de pronóstico detallados
plot_forecast(pep_modelo, pep_close, "30MIN 10D PEP")
plot_forecast(ko_modelo, ko_close, "30MIN 10D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 30MIN 10D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 30MIN 10D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D PEP.xlsx to 30MIN 10D PEP (3).xlsx
Por favor, sube el archivo Excel de 30MIN 10D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D KO.xlsx to 30MIN 10D KO (3).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 30MIN 10D PEP:
Prueba ADF:
Estadístico ADF: -1.1259
p-valor: 0.7046
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}

Prueba KPSS:
Estadístico KPSS: 0.5461
p-valor: 0.0313
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Pruebas de raíz unitaria para 30MIN 10D KO:
Prueba ADF:
Estadístico ADF: -2.4792
p-valor: 0.1206
Valores críticos: {'1%': -3.4756368462466662, '5%': -2.8814104466172608, '10%': -2.5773652982553568}

Prueba KPSS:
Estadístico KPSS: 0.1797
p-valor: 0.1000
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}

Prueba de cointegración de Johansen:
Estadístico de traza: [9.70778532 2.71729012]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
r = 0: No hay cointegración al 95% de confianza
r = 1: No hay cointegración al 95% de confianza
<ipython-input-12-ae55525b6cb1>:50: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is greater than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D PEP:
Orden: (1, 0, 0)
AIC: 332.76
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
Mejor modelo ARMA para 30MIN 10D KO:
Orden: (2, 0, 1)
AIC: -34.51
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Valores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):
150    147.605245
151    147.756244
152    147.903114
153    148.045966
154    148.184912
Name: predicted_mean, dtype: float64

Valores de pronóstico de 30MIN 10D KO (próximos 5 períodos):
150    69.759322
151    69.867988
152    69.984514
153    70.107479
154    70.235438
Name: predicted_mean, dtype: float64
In [13]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud]
ko_close = ko_close[:min_longitud]

# Función para pruebas de raíz unitaria con interpretación
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

# Realizar pruebas de raíz unitaria
unit_root_tests(pep_close, "30MIN 10D PEP")
unit_root_tests(ko_close, "30MIN 10D KO")

# Prueba de cointegración con interpretación
def cointegration_test(df):
    result = coint_johansen(df, det_order=0, k_ar_diff=1)
    print("\nPrueba de cointegración de Johansen:")
    print(f"Estadístico de traza: {result.lr1}")
    print(f"Valores críticos (90%, 95%, 99%): {result.cvt}")
    print("Interpretación:")
    for i in range(len(result.lr1)):
        if result.lr1[i] > result.cvt[i, 1]:
            print(f"  - r = {i}: Existe cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) > valor crítico 95% ({result.cvt[i, 1]:.2f})")
        else:
            print(f"  - r = {i}: No hay cointegración al 95% de confianza")
            print(f"    Estadístico de traza ({result.lr1[i]:.2f}) <= valor crítico 95% ({result.cvt[i, 1]:.2f})")
    if result.lr1[0] > result.cvt[0, 1]:
        print("Conclusión: PEP y KO están cointegrados - comparten una relación de equilibrio a largo plazo")
    else:
        print("Conclusión: No hay evidencia de cointegración entre PEP y KO")

# Preparar datos para cointegración
coint_df = pd.DataFrame({'PEP': pep_close, 'KO': ko_close}).dropna()
cointegration_test(coint_df)

# Función para encontrar el mejor modelo ARMA con interpretación
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    print("Interpretación:")
    print(f"  - p={mejor_orden[0]}: {mejor_orden[0]} término(s) autorregresivo(s)")
    print(f"  - q={mejor_orden[2]}: {mejor_orden[2]} término(s) de media móvil")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA
pep_orden = find_best_arma(pep_close, "30MIN 10D PEP")
ko_orden = find_best_arma(ko_close, "30MIN 10D KO")

pep_modelo = ARIMA(pep_close, order=pep_orden).fit()
ko_modelo = ARIMA(ko_close, order=ko_orden).fit()

# Pronosticar los próximos 30 períodos
pasos_pronostico = 30
pep_pronostico = pep_modelo.forecast(steps=pasos_pronostico)
ko_pronostico = ko_modelo.forecast(steps=pasos_pronostico)

# Crear índice para el pronóstico
ultimo_indice = len(pep_close) - 1
indice_pronostico = range(ultimo_indice + 1, ultimo_indice + 1 + pasos_pronostico)

# Graficar series originales con pronósticos
plt.figure(figsize=(12,6))
plt.plot(pep_close, label='Histórico 30MIN 10D PEP')
plt.plot(indice_pronostico, pep_pronostico, label='Pronóstico 30MIN 10D PEP', color='red')
plt.plot(ko_close, label='Histórico 30MIN 10D KO')
plt.plot(indice_pronostico, ko_pronostico, label='Pronóstico 30MIN 10D KO', color='green')
plt.title('Precios de cierre de 30MIN 10D PEP y 30MIN 10D KO con pronósticos ARMA')
plt.legend()
plt.show()

# Graficar pronóstico detallado con intervalos de confianza e interpretación
def plot_forecast(model, series, name, steps=30):
    forecast_obj = model.get_forecast(steps=steps)
    pronostico = forecast_obj.predicted_mean
    intervalo_conf = forecast_obj.conf_int()

    indice_pronostico = range(len(series), len(series) + steps)

    plt.figure(figsize=(12,6))
    plt.plot(series, label=f'Histórico {name}')
    plt.plot(indice_pronostico, pronostico, label='Pronóstico', color='red')
    plt.fill_between(indice_pronostico,
                     intervalo_conf.iloc[:, 0],
                     intervalo_conf.iloc[:, 1],
                     color='pink',
                     alpha=0.3,
                     label='Intervalo de confianza 95%')
    plt.title(f'Pronóstico ARMA de precio de {name}')
    plt.legend()
    plt.show()

    ultimo_valor = series.iloc[-1]
    promedio_pronostico = pronostico.mean()
    print(f"\nInterpretación del pronóstico para {name}:")
    print(f"Último valor observado: {ultimo_valor:.2f}")
    print(f"Valor promedio del pronóstico: {promedio_pronostico:.2f}")
    print(f"Cambio en el pronóstico: {promedio_pronostico - ultimo_valor:.2f}")
    if promedio_pronostico > ultimo_valor:
        print("Tendencia: Pronóstico al alza")
    elif promedio_pronostico < ultimo_valor:
        print("Tendencia: Pronóstico a la baja")
    else:
        print("Tendencia: Pronóstico estable")
    print(f"Rango del intervalo de confianza 95% en el período {steps}: [{intervalo_conf.iloc[-1, 0]:.2f}, {intervalo_conf.iloc[-1, 1]:.2f}]")

# Generar gráficos de pronóstico detallados e interpretaciones
plot_forecast(pep_modelo, pep_close, "30MIN 10D PEP")
plot_forecast(ko_modelo, ko_close, "30MIN 10D KO")

# Imprimir valores de pronóstico
print("\nValores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):")
print(pep_pronostico[:5])
print("\nValores de pronóstico de 30MIN 10D KO (próximos 5 períodos):")
print(ko_pronostico[:5])
Por favor, sube el archivo Excel de 30MIN 10D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D PEP.xlsx to 30MIN 10D PEP (4).xlsx
Por favor, sube el archivo Excel de 30MIN 10D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D KO.xlsx to 30MIN 10D KO (4).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close

Pruebas de raíz unitaria para 30MIN 10D PEP:
Prueba ADF:
Estadístico ADF: -1.1259
p-valor: 0.7046
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.5461
p-valor: 0.0313
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D PEP es no estacionario

Pruebas de raíz unitaria para 30MIN 10D KO:
Prueba ADF:
Estadístico ADF: -2.4792
p-valor: 0.1206
Valores críticos: {'1%': -3.4756368462466662, '5%': -2.8814104466172608, '10%': -2.5773652982553568}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.1797
p-valor: 0.1000
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser estacionario

Prueba de cointegración de Johansen:
Estadístico de traza: [9.70778532 2.71729012]
Valores críticos (90%, 95%, 99%): [[13.4294 15.4943 19.9349]
 [ 2.7055  3.8415  6.6349]]
Interpretación:
  - r = 0: No hay cointegración al 95% de confianza
    Estadístico de traza (9.71) <= valor crítico 95% (15.49)
  - r = 1: No hay cointegración al 95% de confianza
    Estadístico de traza (2.72) <= valor crítico 95% (3.84)
Conclusión: No hay evidencia de cointegración entre PEP y KO
<ipython-input-13-74d5f4047ecf>:55: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is greater than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D PEP:
Orden: (1, 0, 0)
AIC: 332.76
Interpretación:
  - p=1: 1 término(s) autorregresivo(s)
  - q=0: 0 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
Mejor modelo ARMA para 30MIN 10D KO:
Orden: (2, 0, 1)
AIC: -34.51
Interpretación:
  - p=2: 2 término(s) autorregresivo(s)
  - q=1: 1 término(s) de media móvil
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Interpretación del pronóstico para 30MIN 10D PEP:
Último valor observado: 147.45
Valor promedio del pronóstico: 149.33
Cambio en el pronóstico: 1.88
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [145.25, 156.07]
No description has been provided for this image
Interpretación del pronóstico para 30MIN 10D KO:
Último valor observado: 69.66
Valor promedio del pronóstico: 71.25
Cambio en el pronóstico: 1.59
Tendencia: Pronóstico al alza
Rango del intervalo de confianza 95% en el período 30: [70.57, 73.10]

Valores de pronóstico de 30MIN 10D PEP (próximos 5 períodos):
150    147.605245
151    147.756244
152    147.903114
153    148.045966
154    148.184912
Name: predicted_mean, dtype: float64

Valores de pronóstico de 30MIN 10D KO (próximos 5 períodos):
150    69.759322
151    69.867988
152    69.984514
153    70.107479
154    70.235438
Name: predicted_mean, dtype: float64
In [14]:
import pandas as pd
import numpy as np
from google.colab import files
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.vector_ar.vecm import coint_johansen
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# Subir archivos Excel
print("Por favor, sube el archivo Excel de 30MIN 10D PEP")
pep_upload = files.upload()
pep_filename = list(pep_upload.keys())[0]
pep_df = pd.read_excel(pep_filename)

print("Por favor, sube el archivo Excel de 30MIN 10D KO")
ko_upload = files.upload()
ko_filename = list(ko_upload.keys())[0]
ko_df = pd.read_excel(ko_filename)

# Mostrar columnas disponibles
print("\nColumnas del DataFrame PEP:", list(pep_df.columns))
print("Columnas del DataFrame KO:", list(ko_df.columns))

# Pedir al usuario el nombre de la columna de precios de cierre
columna_cierre = input("Por favor, ingresa el nombre de la columna con los precios de cierre: ")

# Extraer precios de cierre usando el nombre de columna especificado
try:
    pep_close = pep_df[columna_cierre]
    ko_close = ko_df[columna_cierre]
except KeyError:
    print(f"Error: La columna '{columna_cierre}' no se encuentra en uno o ambos DataFrames")
    print("Por favor, verifica los nombres de las columnas e intenta de nuevo")
    raise

# Asegurar misma longitud y eliminar valores nulos
min_longitud = min(len(pep_close), len(ko_close))
pep_close = pep_close[:min_longitud].dropna()
ko_close = ko_close[:min_longitud].dropna()

# Paso 1: Determinar tendencia y estacionalidad
def plot_trend_seasonality(series, name):
    plt.figure(figsize=(12, 6))
    plt.plot(series, label=f'Precios {name}')
    plt.title(f'Precios de cierre de {name}')
    plt.legend()
    plt.show()

    # Descomposición (período 48 para 30 minutos en 10 días: 48 intervalos por día)
    decomposition = seasonal_decompose(series, model='additive', period=48)
    tendencia = decomposition.trend
    estacionalidad = decomposition.seasonal
    residuo = decomposition.resid

    plt.figure(figsize=(12, 8))
    plt.subplot(411)
    plt.plot(series, label='Original')
    plt.legend(loc='upper left')
    plt.subplot(412)
    plt.plot(tendencia, label='Tendencia')
    plt.legend(loc='upper left')
    plt.subplot(413)
    plt.plot(estacionalidad, label='Estacionalidad')
    plt.legend(loc='upper left')
    plt.subplot(414)
    plt.plot(residuo, label='Residuos')
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()

    print(f"\nAnálisis para {name}:")
    print("- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.")
    print("- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.")

plot_trend_seasonality(pep_close, "30MIN 10D PEP")
plot_trend_seasonality(ko_close, "30MIN 10D KO")

# Paso 2: Determinar si los datos son estacionarios
def unit_root_tests(series, name):
    print(f"\nPruebas de raíz unitaria para {name}:")
    adf_result = adfuller(series)
    print("Prueba ADF:")
    print(f'Estadístico ADF: {adf_result[0]:.4f}')
    print(f'p-valor: {adf_result[1]:.4f}')
    print(f'Valores críticos: {adf_result[4]}')
    print("Interpretación:")
    if adf_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser no estacionario")
    kpss_result = kpss(series)
    print("\nPrueba KPSS:")
    print(f'Estadístico KPSS: {kpss_result[0]:.4f}')
    print(f'p-valor: {kpss_result[1]:.4f}')
    print(f'Valores críticos: {kpss_result[3]}')
    print("Interpretación:")
    if kpss_result[1] < 0.05:
        print(f"  - p-valor < 0.05: Rechazar hipótesis nula - {name} es no estacionario")
    else:
        print(f"  - p-valor >= 0.05: No rechazar hipótesis nula - {name} puede ser estacionario")

unit_root_tests(pep_close, "30MIN 10D PEP")
unit_root_tests(ko_close, "30MIN 10D KO")

# Paso 3: Dividir datos en entrenamiento (90%) y prueba (10%)
tamano_entrenamiento = int(len(pep_close) * 0.9)
pep_entrenamiento, pep_prueba = pep_close[:tamano_entrenamiento], pep_close[tamano_entrenamiento:]
ko_entrenamiento, ko_prueba = ko_close[:tamano_entrenamiento], ko_close[tamano_entrenamiento:]

print(f"\nDivisión de datos:")
print(f"PEP - Tamaño entrenamiento: {len(pep_entrenamiento)}, Tamaño prueba: {len(pep_prueba)}")
print(f"KO - Tamaño entrenamiento: {len(ko_entrenamiento)}, Tamaño prueba: {len(ko_prueba)}")

# Función para encontrar el mejor modelo ARMA
def find_best_arma(series, name, max_p=3, max_q=3):
    mejor_aic = float('inf')
    mejor_orden = None

    for p in range(max_p + 1):
        for q in range(max_q + 1):
            try:
                modelo = ARIMA(series, order=(p, 0, q))  # d=0 para ARMA
                resultados = modelo.fit()
                if resultados.aic < mejor_aic:
                    mejor_aic = resultados.aic
                    mejor_orden = (p, 0, q)
            except:
                continue

    print(f"\nMejor modelo ARMA para {name}:")
    print(f"Orden: {mejor_orden}")
    print(f"AIC: {mejor_aic:.2f}")
    return mejor_orden

# Encontrar y ajustar mejores modelos ARMA en datos de entrenamiento
pep_orden = find_best_arma(pep_entrenamiento, "30MIN 10D PEP")
ko_orden = find_best_arma(ko_entrenamiento, "30MIN 10D KO")

pep_modelo = ARIMA(pep_entrenamiento, order=pep_orden).fit()
ko_modelo = ARIMA(ko_entrenamiento, order=ko_orden).fit()

# Pronosticar para el período de prueba
pasos_prueba = len(pep_prueba)
pep_pronostico = pep_modelo.forecast(steps=pasos_prueba)
ko_pronostico = ko_modelo.forecast(steps=pasos_prueba)

# Graficar entrenamiento, prueba y pronóstico
def plot_train_test_forecast(entrenamiento, prueba, pronostico, name):
    indice_pronostico = range(len(entrenamiento), len(entrenamiento) + len(prueba))
    plt.figure(figsize=(12, 6))
    plt.plot(entrenamiento, label=f'{name} Entrenamiento')
    plt.plot(range(len(entrenamiento), len(entrenamiento) + len(prueba)), prueba, label=f'{name} Prueba')
    plt.plot(indice_pronostico, pronostico, label=f'{name} Pronóstico', color='red')
    plt.title(f'{name} Entrenamiento, Prueba y Pronóstico')
    plt.legend()
    plt.show()

plot_train_test_forecast(pep_entrenamiento, pep_prueba, pep_pronostico, "30MIN 10D PEP")
plot_train_test_forecast(ko_entrenamiento, ko_prueba, ko_pronostico, "30MIN 10D KO")

# Evaluar precisión del pronóstico
pep_mse = mean_squared_error(pep_prueba, pep_pronostico)
ko_mse = mean_squared_error(ko_prueba, ko_pronostico)
print(f"\nPrecisión del pronóstico:")
print(f"PEP Error cuadrático medio: {pep_mse:.2f}")
print(f"KO Error cuadrático medio: {ko_mse:.2f}")
Por favor, sube el archivo Excel de 30MIN 10D PEP
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D PEP.xlsx to 30MIN 10D PEP (5).xlsx
Por favor, sube el archivo Excel de 30MIN 10D KO
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving 30MIN 10D KO.xlsx to 30MIN 10D KO (5).xlsx

Columnas del DataFrame PEP: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Columnas del DataFrame KO: ['Unnamed: 0', ' Close', 'Unnamed: 2', 'Unnamed: 3']
Por favor, ingresa el nombre de la columna con los precios de cierre:  Close
No description has been provided for this image
No description has been provided for this image
Análisis para 30MIN 10D PEP:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.
No description has been provided for this image
No description has been provided for this image
Análisis para 30MIN 10D KO:
- Tendencia: Observa el gráfico de tendencia - si tiene pendiente ascendente/descendente, hay tendencia.
- Estacionalidad: Revisa el gráfico de estacionalidad - patrones repetitivos indican estacionalidad.

Pruebas de raíz unitaria para 30MIN 10D PEP:
Prueba ADF:
Estadístico ADF: -1.1259
p-valor: 0.7046
Valores críticos: {'1%': -3.4750180242954167, '5%': -2.8811408028842043, '10%': -2.577221358046935}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D PEP puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.5461
p-valor: 0.0313
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor < 0.05: Rechazar hipótesis nula - 30MIN 10D PEP es no estacionario

Pruebas de raíz unitaria para 30MIN 10D KO:
Prueba ADF:
Estadístico ADF: -2.4792
p-valor: 0.1206
Valores críticos: {'1%': -3.4756368462466662, '5%': -2.8814104466172608, '10%': -2.5773652982553568}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser no estacionario

Prueba KPSS:
Estadístico KPSS: 0.1797
p-valor: 0.1000
Valores críticos: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
Interpretación:
  - p-valor >= 0.05: No rechazar hipótesis nula - 30MIN 10D KO puede ser estacionario

División de datos:
PEP - Tamaño entrenamiento: 135, Tamaño prueba: 15
KO - Tamaño entrenamiento: 135, Tamaño prueba: 15
<ipython-input-14-2215418c0589>:94: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is greater than the p-value returned.

  kpss_result = kpss(series)
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D PEP:
Orden: (1, 0, 0)
AIC: 307.78
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:966: UserWarning: Non-stationary starting autoregressive parameters found. Using zeros as starting parameters.
  warn('Non-stationary starting autoregressive parameters'
/usr/local/lib/python3.11/dist-packages/statsmodels/tsa/statespace/sarimax.py:978: UserWarning: Non-invertible starting MA parameters found. Using zeros as starting parameters.
  warn('Non-invertible starting MA parameters found.'
Mejor modelo ARMA para 30MIN 10D KO:
Orden: (2, 0, 1)
AIC: -30.34
/usr/local/lib/python3.11/dist-packages/statsmodels/base/model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  warnings.warn("Maximum Likelihood optimization failed to "
No description has been provided for this image
No description has been provided for this image
Precisión del pronóstico:
PEP Error cuadrático medio: 10.68
KO Error cuadrático medio: 1.22